/*******************************************************************************
 * Copyright 2011 @ Kapil Viren Ahuja
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.kapilvirenahuja.eamsteps.dataloader.impl;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;

import com.kapil.framework.exception.impl.DataProviderException;
import com.kapil.framework.lang.ObjectFactory;
import com.kapil.framework.lang.ReflectionUtil;
import com.kapil.framework.logger.ILogger;
import com.kapil.framework.logger.LogFactory;
import com.kapilvirenahuja.eamsteps.dataloader.AbstractDataLoader;
import com.kapilvirenahuja.eamsteps.dataloader.IDataLoader;
import com.kapilvirenahuja.eamsteps.form.IDataForm;
import com.kapilvirenahuja.eamsteps.info.HeaderInfo;

/**
 * This implementation of {@link IDataLoader} provides capabilities to read values and create instances of Java Objects
 * of following types. This implementation will check the datatype from the {@link HeaderInfo} class.
 * 
 * <ul>
 * <li>A {@link String}</li>
 * <li>A {@link Integer}</li>
 * <li>A {@link Boolean}</li>
 * <li>A {@link Float}</li>
 * </ul>
 * 
 * @author Kapil Viren Ahuja
 * 
 */
public class NativeDataLoader extends AbstractDataLoader implements IDataLoader
{

    private static final ILogger logger = LogFactory.getInstance().getLogger(NativeDataLoader.class);


    public NativeDataLoader()
    {
        super.next = null;
    }


    public NativeDataLoader(IDataLoader dataLoader)
    {
        super.next = dataLoader;
    }


    /**
     * @see AbstractDataLoader#setup(String, String, HeaderInfo, Object, IDataForm)
     * 
     */
    @Override
    protected void doSetup(String dataTableName, String rowId, String data, HeaderInfo header, Object objectInstance, final IDataForm form)
    {
        if (StringUtils.equalsIgnoreCase(header.getType(), "string") || StringUtils.equalsIgnoreCase(header.getType(), "integer")
                || StringUtils.equalsIgnoreCase(header.getType(), "boolean") || StringUtils.equalsIgnoreCase(header.getType(), "float"))
        {
            logger.debug("Loading native object ## for row ##", new String[] { data, rowId });

            Method setter = ReflectionUtil.findSetter(objectInstance.getClass(), header.getPropertyName());
            if (setter == null)
            {
                throw new DataProviderException("Unable to locate setter for [" + header.getPropertyName() + "]");
            }

            try
            {
                String className = header.getType();
                Object value = ObjectFactory.createInstance(className, data);
                setter.invoke(objectInstance, value);
            }
            catch (Exception ex)
            {
                throw new DataProviderException("Unable to invoke the setter for [" + objectInstance.getClass() + "] on row [" + rowId + "]", ex);
            }
        }

    }

}
